package Flap::App::Cmd::Tool::Controller::DB;
use Flap qw/-b Flap::App::Cmd::Controller -m -s -w/;

sub create_ddl {
    my($self, $c) = @_;
    my $proj = $c->project;
    my $db = $c->args->{DB} || 'Default';
    my $dir = $c->project_root."/db/migrate/$db";
    my $f = '001_init_schema.sql';
    if(-f "$dir/$f"){
        print qq{Overwrite? "$dir/$f" [y] };
        return if <STDIN> !~ /^y?$/;
    }
    
    my $ddl = $proj->storage($db)->create_ddl;
    $proj->OS->mkdir_p($dir) if !-d $dir;
    $proj->OS->cat($ddl, '>', "$dir/$f") || die "$!($dir/$f)";
    print "create: $dir/$f\n";
}

sub dump {
}

sub load {
}

sub migrate {
    my($self, $c) = @_;
    my $proj = $c->project;
    my $db = $c->args->{DB} || 'Default';
    my $dir = $c->project_root."/db/migrate/$db";
    my $storage = $proj->storage($db);
    my $dbh = $proj->dbh($db);
    
    my %v2sql;
    foreach(@{$proj->OS->ls($dir) || die "$!($dir)"}){
        /\.sql\z/ || next;
        /^(\d{3})_/ && $1 ne '000' || die qq{Invalid sql: "$_" in "$dir"};
        die qq{Can't use same version "$_" and "$v2sql{$1}" in "$dir"} if $v2sql{$1};
        $v2sql{$1} = $_;
    }
    
    if($c->args->{CLEANUP}){
        print "Drop all tables. Are you sure? [n] ";
        return if <STDIN> !~ /^y$/;
        my(@sql, $sql);
        push @sql, $sql if ($sql = $storage->disable_constraint_sql);
        push @sql, map{ "drop table $_\n" } $dbh->tables;
        push @sql, $sql if ($sql = $storage->enable_constraint_sql);
        (print "\n$_") && $dbh->do($_) for @sql;
    }
    
    my $s = $proj->schema('SchemaInfo', $db);
    my $r = eval{ $s->find(1) } || $s->new({id => 1, version => 0});
    foreach(sort keys %v2sql){
        next if int($_) <= $r->version;
        
        print qq{Execute? "$dir/$v2sql{$_}" [y] };
        return if !$c->args->{FORCE} && (<STDIN> !~ /^y?$/);
        print "\n" if $c->args->{FORCE};
        
        $proj->OS->cat(my $buf, '<', "$dir/$v2sql{$_}") || die "$!($dir/$v2sql{$_})";
        $buf =~ s%/\*.*?\*/%%sg;
        $buf =~ s/^\s*--.*\n//mg;
        while($buf =~ s/^\s*(.*?);//s){
            print "$1;\n\n";
            $dbh->do("$1");
        }
        die '?' if $buf =~ /\S/;
        $r->version(int($_))->save;
    }
}

sub show_create_database_sql {
    my($self, $c) = @_;
    my $proj = $c->project;
    
    my %host;
    foreach my $db (sort keys %{$proj->config->DB}){
        my $s = $proj->storage($db);
        my $db = $host{$s->host}->{$s->dbname} ||= {sql => $s->create_database_sql};
        $db->{users}{$s->user} = $s->create_user_sql;
    }
    
    my $sql = '';
    foreach my $host (sort keys %host){
        $sql .= "\n" if $sql;
        $sql .= "### $host ###\n";
        foreach my $db (values %{$host{$host}}){
            $sql .= $db->{sql};
            $sql .= $_ for values %{$db->{users}};
        }
    }
    print $sql;
}

1;
